﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Reflection;

namespace Interfleet.SE.UICompiler.Core
{
    /// <summary>
    /// This class builds a string of <see cref="Arguments"/> for the compiler.
    /// </summary>
    public abstract class ArgumentBuilder
    {
        /// <summary>
        /// Full path of the folder of the executing assembly.
        /// </summary>
        protected virtual string AppFolder
        {
            get
            {
                return Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
            }
        }

        /// <summary>
        /// Constructor
        /// </summary>
        /// <param name="arguments"><see cref="Arguments"/> for the compiler</param>
        /// <param name="compileOptions">Compile optinos</param>
        public ArgumentBuilder(Arguments arguments, CompileOptions compileOptions)
            : this(arguments, new FileProvider(), compileOptions)
        {

        }

        /// <summary>
        /// Constructor
        /// </summary>
        /// <param name="arguments"><see cref="Arguments"/> for the compiler</param>
        /// <param name="fileInfoProvider">The <see cref="IFileProvider"/></param>
        /// <param name="compileOptions">Compile optinos</param>
        /// <exception cref="ArgumentNullException">If <paramref name="arguments"/>, <paramref name="fileInfoProvider"/>,
        /// or <paramref name="compileOptions"/> is null</exception>
        /// <exception cref="ArgumentException">If <paramref name="arguments"/>.CompileOption is not defined in <paramref name="compileOptions"/></exception>
        public ArgumentBuilder(Arguments arguments, IFileProvider fileInfoProvider, CompileOptions compileOptions)
        {
            if (arguments == null)
            {
                throw new ArgumentNullException("arguments", "value cannot be null");
            }
            if (fileInfoProvider == null)
            {
                throw new ArgumentNullException("fileSizeProvider", "value cannot be null");
            }
            if (compileOptions.Options.Length > 0)
            {
                if (string.IsNullOrEmpty(arguments.CompileOption))
                {
                    arguments.CompileOption = compileOptions.DefaultOption;
                }
                if (string.IsNullOrEmpty(arguments.CompileOption))
                {
                    throw new ArgumentNullException("arguments.CompileOption", "value cannot be null or empty");
                }
                if (!compileOptions.Options.Contains(arguments.CompileOption))
                {
                    throw new ArgumentException("arguments.CompileOption", string.Format("Invalid CompileOption: '{0}'", arguments));
                }
            }
            Arguments = arguments;
            FileProvider = fileInfoProvider;
        }

        /// <summary>
        /// Arguments for compilation
        /// </summary>
        protected Arguments Arguments
        {
            get;
            private set;
        }

        /// <summary>
        /// An instance of <see cref="IFileProvider"/>
        /// </summary>
        protected IFileProvider FileProvider
        {
            get;
            private set;
        }

        /// <summary>
        /// Builds up arguments as a <see cref="System.String"/>
        /// </summary>
        /// <returns></returns>
        public abstract string Build();
       
    }
}
